package com.aspire.aimini.controller;

import com.aspire.aimini.model.Result;
import com.aspire.aimini.model.dto.UserDTO;
import com.aspire.aimini.model.query.UserQuery;
import com.aspire.aimini.service.UserService;
import com.aspire.aimini.util.IpUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;


import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * 用户控制器
 *
 * @author wangguiyou
 * @date 2024-12-19
 * @description 用户相关API接口
 */
@Slf4j
@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
@Validated
@Tag(name = "用户管理", description = "用户相关API接口")
public class UserController {

    private final UserService userService;

    /**
     * 用户注册
     */
    @PostMapping("/register")
    @Operation(summary = "用户注册", description = "新用户注册")
    public Result<Boolean> register(
            @Valid @RequestBody UserDTO userDTO) {
        boolean result = userService.register(userDTO);
        return Result.success(result, "注册成功");
    }

    /**
     * 用户登录
     */
    @PostMapping("/login")
    @Operation(summary = "用户登录", description = "用户登录获取Token")
    public Result<Map<String, String>> login(
            @Parameter(description = "登录请求") @Valid @RequestBody LoginRequest request,
            HttpServletRequest httpRequest) {
        String loginIp = IpUtil.getClientIp(httpRequest);
        String token = userService.login(request.getUsername(), request.getPassword(), loginIp);
        return Result.success(Collections.singletonMap("token", token), "登录成功");
    }

    /**
     * 分页查询用户列表
     */
    @GetMapping
    @Operation(summary = "分页查询用户列表", description = "根据条件分页查询用户列表")
    public Result<IPage<UserDTO>> pageUsers(
            @Parameter(description = "查询条件") @Valid UserQuery query) {
        IPage<UserDTO> page = userService.pageUsers(query);
        return Result.success(page);
    }

    /**
     * 根据ID查询用户详情
     */
    @GetMapping("/{id}")
    @Operation(summary = "查询用户详情", description = "根据用户ID查询用户详情")
    public Result<UserDTO> getUserById(
            @Parameter(description = "用户ID") @PathVariable @NotNull Long id) {
        UserDTO user = userService.getUserById(id);
        return Result.success(user);
    }

    /**
     * 创建用户
     */
    @PostMapping
    @Operation(summary = "创建用户", description = "管理员创建新用户")
    public Result<Boolean> createUser(
            @Valid @RequestBody UserDTO userDTO) {
        boolean result = userService.createUser(userDTO);
        return Result.success(result, "创建成功");
    }

    /**
     * 更新用户信息
     */
    @PutMapping("/{id}")
    @Operation(summary = "更新用户信息", description = "根据用户ID更新用户信息")
    public Result<Boolean> updateUser(
            @Parameter(description = "用户ID") @PathVariable @NotNull Long id,
            @Valid @RequestBody UserDTO userDTO) {
        boolean result = userService.updateUser(id, userDTO);
        return Result.success(result, "更新成功");
    }

    /**
     * 删除用户
     */
    @DeleteMapping("/{id}")
    @Operation(summary = "删除用户", description = "根据用户ID删除用户")
    public Result<Boolean> deleteUser(
            @Parameter(description = "用户ID") @PathVariable @NotNull Long id) {
        boolean result = userService.deleteUser(id);
        return Result.success(result, "删除成功");
    }

    /**
     * 批量删除用户
     */
    @DeleteMapping("/batch")
    @Operation(summary = "批量删除用户", description = "根据用户ID列表批量删除用户")
    public Result<Boolean> batchDeleteUsers(
            @Parameter(description = "用户ID列表") @RequestBody @NotEmpty List<Long> ids) {
        boolean result = userService.batchDeleteUsers(ids);
        return Result.success(result, "批量删除成功");
    }

    /**
     * 更新用户状态
     */
    @PutMapping("/{id}/status")
    @Operation(summary = "更新用户状态", description = "启用或禁用用户")
    public Result<Boolean> updateUserStatus(
            @Parameter(description = "用户ID") @PathVariable @NotNull Long id,
            @Parameter(description = "状态请求") @Valid @RequestBody StatusRequest request) {
        boolean result = userService.updateUserStatus(id, request.getStatus());
        return Result.success(result, "状态更新成功");
    }

    /**
     * 批量更新用户状态
     */
    @PutMapping("/batch/status")
    @Operation(summary = "批量更新用户状态", description = "批量启用或禁用用户")
    public Result<Boolean> batchUpdateUserStatus(
            @Parameter(description = "批量状态请求") @Valid @RequestBody BatchStatusRequest request) {
        boolean result = userService.batchUpdateUserStatus(request.getIds(), request.getStatus());
        return Result.success(result, "批量状态更新成功");
    }

    /**
     * 重置用户密码
     */
    @PutMapping("/{id}/password/reset")
    @Operation(summary = "重置用户密码", description = "管理员重置用户密码")
    public Result<Boolean> resetPassword(
            @Parameter(description = "用户ID") @PathVariable @NotNull Long id,
            @Parameter(description = "重置密码请求") @Valid @RequestBody ResetPasswordRequest request) {
        boolean result = userService.resetPassword(id, request.getNewPassword());
        return Result.success(result, "密码重置成功");
    }

    /**
     * 修改用户密码
     */
    @PutMapping("/{id}/password/change")
    @Operation(summary = "修改用户密码", description = "用户修改自己的密码")
    public Result<Boolean> changePassword(
            @Parameter(description = "用户ID") @PathVariable @NotNull Long id,
            @Parameter(description = "修改密码请求") @Valid @RequestBody ChangePasswordRequest request) {
        boolean result = userService.changePassword(id, request.getOldPassword(), request.getNewPassword());
        return Result.success(result, "密码修改成功");
    }

    /**
     * 检查用户名是否存在
     */
    @GetMapping("/check/username")
    @Operation(summary = "检查用户名是否存在", description = "检查用户名是否已被使用")
    public Result<Boolean> checkUsername(
            @Parameter(description = "用户名") @RequestParam @NotBlank String username,
            @Parameter(description = "排除的用户ID") @RequestParam(required = false) Long excludeId) {
        boolean exists = userService.isUsernameExists(username, excludeId);
        return Result.success(exists);
    }

    /**
     * 检查邮箱是否存在
     */
    @GetMapping("/check/email")
    @Operation(summary = "检查邮箱是否存在", description = "检查邮箱是否已被使用")
    public Result<Boolean> checkEmail(
            @Parameter(description = "邮箱") @RequestParam @NotBlank String email,
            @Parameter(description = "排除的用户ID") @RequestParam(required = false) Long excludeId) {
        boolean exists = userService.isEmailExists(email, excludeId);
        return Result.success(exists);
    }

    /**
     * 检查手机号是否存在
     */
    @GetMapping("/check/phone")
    @Operation(summary = "检查手机号是否存在", description = "检查手机号是否已被使用")
    public Result<Boolean> checkPhone(
            @Parameter(description = "手机号") @RequestParam @NotBlank String phone,
            @Parameter(description = "排除的用户ID") @RequestParam(required = false) Long excludeId) {
        boolean exists = userService.isPhoneExists(phone, excludeId);
        return Result.success(exists);
    }

    /**
     * 获取用户统计信息
     */
    @GetMapping("/statistics")
    @Operation(summary = "获取用户统计信息", description = "获取用户数量统计信息")
    public Result<UserService.UserStatistics> getUserStatistics() {
        UserService.UserStatistics statistics = userService.getUserStatistics();
        return Result.success(statistics);
    }

    // 内部请求类

    /**
     * 登录请求
     */
    @io.swagger.v3.oas.annotations.media.Schema(description = "登录请求")
    public static class LoginRequest {
        @io.swagger.v3.oas.annotations.media.Schema(description = "用户名", example = "admin")
        @NotBlank(message = "用户名不能为空")
        private String username;

        @io.swagger.v3.oas.annotations.media.Schema(description = "密码", example = "123456")
        @NotBlank(message = "密码不能为空")
        private String password;

        // getters and setters
        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }
    }

    /**
     * 状态请求
     */
    @io.swagger.v3.oas.annotations.media.Schema(description = "状态请求")
    public static class StatusRequest {
        @io.swagger.v3.oas.annotations.media.Schema(description = "状态（1-启用，0-禁用）", example = "1")
        @NotNull(message = "状态不能为空")
        private Integer status;

        // getters and setters
        public Integer getStatus() {
            return status;
        }

        public void setStatus(Integer status) {
            this.status = status;
        }
    }

    /**
     * 批量状态请求
     */
    @io.swagger.v3.oas.annotations.media.Schema(description = "批量状态请求")
    public static class BatchStatusRequest {
        @io.swagger.v3.oas.annotations.media.Schema(description = "用户ID列表")
        @NotEmpty(message = "用户ID列表不能为空")
        private List<Long> ids;

        @io.swagger.v3.oas.annotations.media.Schema(description = "状态（1-启用，0-禁用）", example = "1")
        @NotNull(message = "状态不能为空")
        private Integer status;

        // getters and setters
        public List<Long> getIds() {
            return ids;
        }

        public void setIds(List<Long> ids) {
            this.ids = ids;
        }

        public Integer getStatus() {
            return status;
        }

        public void setStatus(Integer status) {
            this.status = status;
        }
    }

    /**
     * 重置密码请求
     */
    @io.swagger.v3.oas.annotations.media.Schema(description = "重置密码请求")
    public static class ResetPasswordRequest {
        @io.swagger.v3.oas.annotations.media.Schema(description = "新密码", example = "123456")
        @NotBlank(message = "新密码不能为空")
        private String newPassword;

        // getters and setters
        public String getNewPassword() {
            return newPassword;
        }

        public void setNewPassword(String newPassword) {
            this.newPassword = newPassword;
        }
    }

    /**
     * 修改密码请求
     */
    @io.swagger.v3.oas.annotations.media.Schema(description = "修改密码请求")
    public static class ChangePasswordRequest {
        @io.swagger.v3.oas.annotations.media.Schema(description = "原密码", example = "123456")
        @NotBlank(message = "原密码不能为空")
        private String oldPassword;

        @io.swagger.v3.oas.annotations.media.Schema(description = "新密码", example = "654321")
        @NotBlank(message = "新密码不能为空")
        private String newPassword;

        // getters and setters
        public String getOldPassword() {
            return oldPassword;
        }

        public void setOldPassword(String oldPassword) {
            this.oldPassword = oldPassword;
        }

        public String getNewPassword() {
            return newPassword;
        }

        public void setNewPassword(String newPassword) {
            this.newPassword = newPassword;
        }
    }
}